package com.cskaoyan.shopping.service.impl;

import com.cskaoyan.mall.commons.result.UserLoginMsg;
import com.cskaoyan.mall.commons.util.GetUserInfoUtils;
import com.cskaoyan.shopping.converter.CartItemConverter;
import com.cskaoyan.shopping.dal.entitys.Item;
import com.cskaoyan.shopping.dal.persistence.ItemMapper;
import com.cskaoyan.shopping.dto.CartProductDto;
import com.cskaoyan.shopping.form.CartRequest;
import com.cskaoyan.shopping.form.CheckAllItemRequest;
import com.cskaoyan.shopping.service.ICartService;
import com.cskaoyan.user.dal.entitys.UserVerify;
import com.cskaoyan.user.dal.persistence.UserVerifyMapper;
import org.redisson.api.RMap;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotNull;
import java.util.*;

/**
 * @description: 购物车模块
 * @date 2023/1/10 10:11
 */
@Service
public class ICartServiceImpl implements ICartService {

    @Autowired
    ItemMapper itemMapper;

    @Autowired(required = false)
    CartItemConverter cartItemConverter;

    @Autowired
    RedissonClient redissonClient;


    /**
     * 获得购物车商品列表
     *
     * @param userCartKey
     * @return
     */
    @Override
    public List<CartProductDto> getCartListById(String userCartKey) {

        // hash --> key:userId(表名),field:productId — value:CartProductDto对象(商品Id-购物车商品对象)
        RMap<Long, CartProductDto> map = redissonClient.getMap(String.valueOf(userCartKey));
        List<CartProductDto> cartList = new ArrayList<>();
        Set<Map.Entry<Long, CartProductDto>> entries = map.entrySet();
        for (Map.Entry<Long, CartProductDto> entry : entries) {
            CartProductDto cart = entry.getValue();
            cartList.add(cart);
        }

        return cartList;
    }


    @Override
    public void addToCart(CartRequest request,String username) {

        //获取商品id&数量num,userid
        Long productId = request.getProductId();
        String userId = request.getUserId().toString();
        Long productNum = request.getProductNum().longValue();

        //username+userid作为辨识(new)
        String userInfo = username+userId;

        //获取用户购物车信息(new)
        RMap<Long, CartProductDto> map = redissonClient.getMap(userInfo);

        //查询商品
        Item item = itemMapper.selectByPrimaryKey(productId);

        //转化成DTO对象
        CartProductDto cartProductDto = cartItemConverter.item2Dto(item);
        cartProductDto.setProductNum(productNum);
        cartProductDto.setChecked("true");

        //根据商品id获取商品信息(new)
        CartProductDto productDtos = map.get(request.getProductId());
        //判断购物车中是否有改商品
        if (map.containsKey(request.getProductId())){
            //更新数量
            productDtos.setProductNum(productDtos.getProductNum()+request.getProductNum());
            map.put(productId,productDtos);
        } else {
            map.put(productId,cartProductDto);
        }

    }

    /**
     * 更新购物车中的商品
     * @param request
     */
    @Override
    public void updateCartNum(CartRequest cartRequest, HttpServletRequest request) {

        @NotNull String userId = String.valueOf(cartRequest.getUserId());
        UserLoginMsg userLoginMsg = GetUserInfoUtils.getUserInfo(request);
        String username = userLoginMsg.getUsername();
        String userCartKey = username + userId;
        // 要修改商品的id
        @NotNull Long productId = cartRequest.getProductId();
        // 要修改的数量
        Long productNum = cartRequest.getProductNum().longValue();
        // 要修改的选择状态
        String checked = cartRequest.getChecked();

        RMap<Long, CartProductDto> map = redissonClient.getMap(userCartKey);
        Set<Map.Entry<Long, CartProductDto>> entries = map.entrySet();
        for (Map.Entry<Long, CartProductDto> entry : entries) {
            Long key = entry.getKey();
            if (key.equals(productId)) {
                CartProductDto productDto = entry.getValue();
                // 修改数量
                productDto.setProductNum(productNum);
                // 修改选择状态
                productDto.setChecked(checked);
                entry.setValue(productDto);
            }
        }
    }

    /**
     * 全选/全不选购物车中的所有商品
     * @param checkAllItemRequest
     * @param userCartKey
     */
    @Override
    public void checkAllCartItem(CheckAllItemRequest checkAllItemRequest, String userCartKey) {
        List<CartProductDto> list = getCartListById(userCartKey);
        RMap<Long, CartProductDto> map = redissonClient.getMap(userCartKey);
        for (CartProductDto cartProductDto : list) {
            cartProductDto.setChecked(checkAllItemRequest.getChecked());
            map.put(cartProductDto.getProductId(), cartProductDto);
        }
    }

    /**
     * 删除购物车中的商品
     *
     * @param uid    用户id
     * @param itemId 商品id
     */
    @Override
    public void deleteCartItem(Long uid, Long itemId, UserLoginMsg user) {

        //查询该商品，并将其转化为Dto对象
        Item item = itemMapper.selectByPrimaryKey(itemId);
        CartProductDto cartProductDto = cartItemConverter.item2Dto(item);

        //根据用户的id查询其info
        //UserVerify userVerify = userVerifyMapper.selectByPrimary(uid);
        //String username = userVerify.getUsername();
        String userInfo = user.getUsername() + user.getUid();

        //从redis中删除
        RMap<String, CartProductDto> map = redissonClient.getMap(userInfo);

        map.remove(itemId);


    }

    /**
     * 删除购物车中选中的商品
     * @param userId
     * @param request
     */
    @Override
    public void deleteCheckedItem(Long userId, HttpServletRequest request) {

        UserLoginMsg userLoginMsg = GetUserInfoUtils.getUserInfo(request);
        String username = userLoginMsg.getUsername();
        String userCartKey = username + userId;

        RMap<Long, CartProductDto> map = redissonClient.getMap(userCartKey);
        Set<Map.Entry<Long, CartProductDto>> entries = map.entrySet();
        for (Map.Entry<Long, CartProductDto> entry : entries) {
            CartProductDto productDto = entry.getValue();
            if (productDto.getChecked().equals("true")){
                map.remove(entry.getKey());
            }
        }

    }

}
